import $service from '../../../../service'
const AgoraMiniappSDK = require("agora-miniapp-sdk");
const max_user = 10
const app = getApp();


Component({
  data: {
    pusher: null,
    playerList: [],
    media: [],
    config: null,
    getPusherStream: '',
    getDoctorStream: []
  },
  lifetimes:{
    async ready() {
      let config = wx.getStorageSync('cTencentConfig')
      if (!config) {
        wx.showToast({
            title: '请先配置声网TRTC参数',
        })
        return
      }
      this.setData({
        config: {
          ...config,
          // appId: 'e1ed60810ee2479591fc0fe1dc00523b',
          // sig: '007eJxTYNhZ+ESs50zNP30x53t2leXrT8ryMXT/V3mySzAqYGb8yt8KDKmGqSlmBhaGBqmpRibmlqaWhmnJBmmphinJBgamRsZJrJsi0xsCGRl0ed6wMjJAIIjPxGBsycAAAASZHX0='
        }
      })
      if (!config.room) {
        wx.showToast({
          title: '请先配置声网TRTC参数room',
        })
        return
      }
      if (!config.appId) {
        wx.showToast({
          title: '请先配置声网TRTC参数appId',
        })
        return
      }
        if (!config.sig) {
            wx.showToast({
                title: '请先配置声网TRTC参数sig',
            })
            return
        }
      this.client = null
      try {
        console.log('this.setData',this.data.config)
        const {userId, room} = this.data.config
        const url = await this.initAgoraChannel(userId, room)
        console.log(`channel: ${room}, uid: ${userId}, pushing ${url}`);
        let ts = new Date().getTime();
        this.addMedia(0, userId, url, {
          key: ts
        });
        // }
      } catch (e) {
        console.log(e, 123123123123123)
        wx.showToast({
          title: `客户端初始化失败`,
          icon: 'none',
          duration: 5000
        });
      }
    },
    detached: function () {
    },
  },

  methods: {
    /**
     * 获取流
     */
    // 自己
    async getPusherStream() {
      let media = this.data.media || [];
      let pusher = media.find(item => {
        return item.type === 0
      });
      console.log('pusher',pusher)
      return pusher ? pusher.url : '';
    },
    // 医生
    async getDoctorStream() {
      let media = this.data.media || [];
      let doctor = media.filter(item => {
        return item.type === 1
      });
      console.log('doctor',doctor)
      return doctor
    },
    /**
     * 初始化sdk推流
     */
    async initAgoraChannel(userId, room) {
      this.client = new AgoraMiniappSDK.Client({
        mode: 'rtc',
        codec: 'vp8' // Web端如果使用h
      })
      console.log(this.client, 'client')
      // set log level
      AgoraMiniappSDK.LOG.setLogLevel(-1);
      //subscribe stream events
      this.subscribeEvents();
      await this.client.init(this.data.config.appId)
      await this.client.setRole('broadcaster')
      await this.client.join(this.data.config.sig, room, userId)
      let url = await this.client.publish(url);
      this.videoRecord(1)
      console.log('urlurlurlurl',url)
      return url
    },

    // 视频录制 1开始录制 2结束录制
    async videoRecord(type) {
      console.log('失败',type)
      if (JSON.parse($service.getStore('userInfo')).type === 'D') {
        await app.http.videoStartOrEnd({
          "cname": this.data.config.room,
          "status": type
        }).catch(err => {
          wx.showToast({
            title: err.msg,
            icon: 'none',
            duration: 5000
          });
        })
      }
    },


    async reinitAgoraChannel(uid, channel) {
      this.client = new AgoraMiniappSDK.Client({
        mode: 'rtc',
        codec: 'h264' // Web端如果使用h264，这里需要相应修改
      })
      AgoraMiniappSDK.LOG.setLogLevel(-1);
      this.subscribeEvents();
      let uids = this.data.media.map(item => {
        return item.uid;
      });
      await this.client.init(this.data.config.appId)
      await this.client.setRole('broadcaster');
      await this.client.rejoin(undefined, channel, uid, uids)
      let url = ''
      url = await this.client.publish()
      return url
    },

    addMedia(mediaType, uid, url, options) {
      console.log(`add media ${mediaType} ${uid} ${url}`);
      let media = this.data.media || [];
      if (mediaType === 0) {
        //pusher
        media.splice(0, 0, {
          key: options.key,
          type: mediaType,
          uid: `${uid}`,
          holding: false,
          url: url,
          left: 0,
          top: 0,
          width: 0,
          height: 0
        });
      } else {
        //player
        media.push({
          key: options.key,
          rotation: options.rotation,
          type: mediaType,
          uid: `${uid}`,
          holding: false,
          url: url,
          left: 0,
          top: 0,
          width: 0,
          height: 0
        });
      }
      return this.refreshMedia(media);
    },
    /**
     * 注册stream事件
     */
    subscribeEvents() {
      /**
       * fired when new stream join the channel
       */
      this.client.on("stream-added", async e => {
        console.log('医生加入了', e)
        let uid = e.uid;
        const ts = new Date().getTime();
        /**
         * subscribe to get corresponding url
         */
        const { url, rotation } = await this.client.subscribe(uid);
        let media = this.data.media || [];
        let matchItem = null;
        for (let i = 0;i < media.length;i++) {
          let item = this.data.media[i];
          if (item.uid == uid) {
            matchItem = item;
            break;
          }
        }
        if (!matchItem) {
          this.addMedia(1, uid, url, {
            key: ts,
            rotation: rotation
          })
        } else {
          this.updateMedia(matchItem.uid, {
            url: url,
            key: ts,
          });
        }
      });

      /**
       * remove stream when it leaves the channel
       */
      this.client.on("stream-removed", e => {
        this.removeMedia(e.uid);
      });

      /**
       * when bad thing happens - we recommend you to do a
       * full reconnect when meeting such error
       * it's also recommended to wait for few seconds before
       * reconnect attempt
       */
      this.client.on("error", err => {
        let errObj = err || {};
        let code = errObj.code || 0;
        let reason = errObj.reason || "";
        console.log(`error: ${code}, reason: ${reason}`);
        if (code === 501 || code === 904) {
          this.reconnect();
        }
      });

      /**
       * there are cases when server require you to update
       * player url, when receiving such event, update url into
       * corresponding live-player, REMEMBER to update key property
       * so that live-player is properly refreshed
       * NOTE you can ignore such event if it's for pusher or happens before
       * stream-added
       */
      this.client.on('update-url', e => {
        let uid = e.uid;
        let url = e.url;
        let ts = new Date().getTime();
        if (uid == this.data.config.userId) {
          console.log(`ignore update-url`);
        } else {
          this.updateMedia(uid, {
            url: url,
            key: ts,
          });
        }
      });

      this.client.on("token-privilege-will-expire", () => {
        console.log("当前 token 即将过期，请更新 token");
      });

      this.client.on("token-privilege-did-expire", () => {
        console.log("当前 token 已过期，请更新 token 并重新加入频道");
      });
    },

    /**
     * remove media from view
     */
    removeMedia(uid) {
      let media = this.data.media || [];
      media = media.filter(item => {
        return `${item.uid}` !== `${uid}`
      });

      if (media.length !== this.data.media.length) {
        this.refreshMedia(media);
      } else {
        return Promise.resolve();
      }
    },
    /**
     * update media object
     * the media component will be fully refreshed if you try to update key
     * property.
     */
    updateMedia(uid, options) {
      let media = this.data.media || [];
      let changed = false;
      for (let i = 0;i < media.length;i++) {
        let item = media[i];
        if (`${item.uid}` === `${uid}`) {
          media[i] = Object.assign(item, options);
          changed = true;
          console.log(`after update media ${uid} ${JSON.stringify(item)}`)
          break;
        }
      }

      if (changed) {
        return this.refreshMedia(media);
      } else {
        console.log(`media not changed: ${JSON.stringify(media)}`)
        return Promise.resolve();
      }
    },


    /**
     * call setData to update a list of media to this.data.media
     * this will trigger UI re-rendering
     */
    refreshMedia(media) {
      return new Promise((resolve) => {
        for (let i = 0;i < media.length;i++) {
          if (i < max_user) {
            //show
            media[i].holding = false;
          } else {
            //hide
            media[i].holding = true;
          }
        }
        console.log('刷新了')
        if (media.length > max_user) {
          wx.showToast({
            title: `由于房内人数超过${max_user}人，部分视频未被加载显示`,
          });
        }

        console.log(`updating media: `, media);
        this.setData({
          media: media
        }, () => {
          console.log('media updated');
          this.setData({
            getPusherStream: this.getPusherStream(),
            getDoctorStream: this.getDoctorStream()
          }, () => {
            resolve()
          })
        });

      });
    },

    /**
     * reconnect when bad things happens...
     */
    async reconnect() {
      wx.showToast({
        title: `尝试恢复链接...`,
        icon: 'none',
        duration: 5000
      });
      // always destroy client first
      // *important* miniapp supports 5 websockets maximum at same time
      // do remember to destroy old client first before creating new ones
      await this.client.destroy();
      this.reconnectTimer = setTimeout(async () => {
        const {userId, room} = this.data.config
        try {
          const url = await this.reinitAgoraChannel(userId, room)
          let ts = new Date().getTime();
          if (this.hasMedia(0, userId)) {
            this.updateMedia(userId, {
              url: url,
              key: ts,
            });
          } else {
            // pusher not exists in media list
            console.log(`pusher not yet exists when rejoin...adding`);
            this.addMedia(0, userId, url, {
              key: ts
            });
          }
          // }
        } catch (e) {
          console.log(`reconnect failed: ${e}`);
          // remember control max reconnect times
          return this.reconnect();
        }
      }, 1 * 1000);
    },

    /**
     * check if current media list has specified uid & mediaType component
     */
    hasMedia(mediaType, uid) {
      let media = this.data.media || [];
      return media.filter(item => {
        return item.type === mediaType && item.uid == uid
      }).length > 0
    },

    /**
     * return player component via uid
     */
    getPlayerComponent(uid) {
      return this.selectComponent(`#rtc-player-${uid}`);
    },

    /**
     * return pusher component
     */
    getPusherComponent() {
      return this.selectComponent(`#rtc-pusher`);
    },



    // 请保持跟 wxml 中绑定的事件名称一致
    _pusherStateChangeHandler(event) {
      // this.TRTC.pusherEventHandler(event)
    },
    _pusherNetStatusHandler(event) {
      // this.TRTC.pusherNetStatusHandler(event)
    },
    _playerStateChange(event) {
      // this.TRTC.playerEventHandler(event)
    },
    _playerNetStatus(event) {
      // this.TRTC.playerNetStatus(event)
    },

    exitRoom() {
      this.client.leave()
      this.videoRecord(2)
      this.setData({
        media: []
      })
      this.setData({
        getPusherStream: '',
        getDoctorStream: []
      })

    },
    // *************



    openSetting() {
      return new Promise((resolve, reject) => {
        wx.showModal({
          title: '温馨提示',
          content: '请授权微信小程序麦克风与摄像头权限，以使用视频功能',
          success: (res) => {
            if (res.confirm) {
              wx.openSetting({
                success: function (res) {
                  console.log('打开权限设置页面', res)
                  // const authSettingObj = res.authSetting
                  return resolve(true)
                },
              })
            } else {
              return reject()
            }
          },
          fail: (err) => {
            return reject()
          },
        })
      })
    },
    checkPermisson() {
      return new Promise((resolve, reject) => {
        wx.getSetting({
          success: async (res) => {
            const authSettingObj = res.authSetting
            console.log(authSettingObj)
            if (authSettingObj['scope.camera'] === true && authSettingObj['scope.record'] === true) {
              // 当前已经有权限了
              console.log('当前已经有视频录音权限了')
              return resolve(true)
            } else if (authSettingObj['scope.camera'] === false || authSettingObj['scope.record'] === false) {
              // 之前问过权限，但是拒绝了
              console.log('之前问过权限，但是拒绝了')
              // 打开setting
              await this.openSetting()
              try {
                return resolve(true)
              } catch {
                return reject(false)
              }
            } else {
              // 还没问过权限
              console.log('还没问过权限')
              // 去请求授权
              wx.authorize({
                success: (res) => {
                  return resolve(true)
                },
                fail: async (err) => {
                  // 拒绝授权了
                  // 打开setting
                  try {
                    await this.openSetting()
                    return resolve(true)
                  } catch {
                    return reject(false)
                  }
                },
              })
            }
          },
        })
      })
    }
  }
})
